home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * SGCOPY.C V1.1
- *
- * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
- *
- * GET-COPY SERVER (NEW COPY SERVER)
- *
- * The current version only accepts one connection at a time. This server
- * will send requested files to the remote machine.
- *
- * length in 68000 longword format.
- *
- * ACCESS RESTRICTIONS:
- *
- * Remote access restrictions are according to DNET_GROUP or DNET_READ
- *
- * DNET_READ >= 9 Full Access
- * DNET_READ < 9 According to comment field (AC=n) or group acc.
- * (GR=n) matches DNET_GROUP)
- *
- * When searching for access rights, the comment field of the file/dir
- * requested is checked first. If empty, the parent dir is checked.
- * This continues (parent diring) until root is found or a comment
- * field with access info in it.
- */
-
- #include "defs.h"
-
- typedef struct {
- char Cmd;
- char Str[64];
- long Val;
- } HDR;
-
- extern int Enable_Abort;
- char Buf[8192];
- void *Chan;
-
- void SGCopy ARGS((void));
- int PutObject ARGS((char *));
- int PutDir ARGS((char *, int));
- int PutFile ARGS((char *, int));
- int WriteHeader ARGS((char, char *, long));
- int ReadHeader ARGS((HDR *));
-
- int
- brk()
- {
- return(0);
- }
-
- void
- #ifdef LATTICE
- _main(str)
- #else
- _main(len,str)
- #endif
- char *str;
- {
- struct MsgPort *port;
- PROC *myproc = (PROC *)FindTask(NULL);
- long savedir;
- long mask, rmask;
-
- onbreak(brk);
-
- if (strncmp(str, "__dnet", 6) != 0) {
- Version("SGCopy", VERSION, SGCOPY_VERSION);
- _exit(0);
- }
-
- port = DListen(PORT_GFILECOPY);
- WaitPort(&myproc->pr_MsgPort);
- ReplyMsg(GetMsg(&myproc->pr_MsgPort));
- savedir = Lock("", SHARED_LOCK); /* duplicate current dir */
- if (!savedir) {
- DUnListen(port);
- _exit(1);
- }
- savedir = CurrentDir(savedir); /* CD dup, returns original */
- mask = SIGBREAKF_CTRL_C|(1 << port->mp_SigBit);
- for (;;) {
- long dupdir = DupLock(myproc->pr_CurrentDir);
- rmask = Wait(mask);
- if (rmask & SIGBREAKF_CTRL_C) {
- UnLock(CurrentDir(dupdir));
- break;
- }
- while (Chan = DAccept(port)) {
- SGCopy();
- DClose(Chan);
- }
- UnLock(CurrentDir(dupdir));
- }
- UnLock(CurrentDir(savedir)); /* restore original */
- DUnListen(port);
- }
-
- void
- SGCopy()
- {
- short error;
- static HDR Hdr;
-
- error = WriteHeader('H', "Hello, GCopy server V1.30", 0);
- if (error)
- return;
- switch(ReadHeader(&Hdr)) {
- case -1:
- return;
- case 'H':
- break;
- }
- while (!error) {
- switch(ReadHeader(&Hdr)) {
- case 'G':
- error = PutObject(Hdr.Str);
- break;
- case 'E':
- goto done;
- case 'P': /* put-files, not implemented */
- default:
- error = 1;
- break;
- }
- }
- done:
- ;
- }
-
- int
- PutObject(str)
- char *str;
- {
- long lock;
- FIB *fib = malloc(sizeof(FIB));
- short error = 0;
- short access = GetEnvVal(DNET_READ);
- short group = GetEnvVal(DNET_GROUP);
-
- mountrequest(0);
- lock = Lock(str, SHARED_LOCK);
- mountrequest(1);
- if (lock == NULL || !Examine(lock, fib)) { /* unable to find it! */
- error = WriteHeader('N', "Unable to find object", 0);
- goto done;
- }
-
- /*
- * Determine Access rights
- *
- * If the file/dir or any parent dir has AC > your_ac, access is
- * denied. If the file/dir and all parent dirs have neither an ACcess
- * or GRoup entry, access is denied. If a group entry is found that
- * matches your group, access is allowed (unless an AC is found > your_ac)
- *
- * If your_ac is >= 9, no access checking of parent directories is
- * done at all. However, access checking of downloaded files will
- * be done, and any AC values > your_ac will be disalloweds.
- */
-
- if (access < 9) { /* must check comment/access */
- short ok = 0;
- long lock2 = DupLock(lock);
- long tmp;
- for (;;) {
- short ac = 0;
-
- while (ac >= 0) { /* check groups */
- short idx = 0;
- ac = ExtractFieldVal(fib->fib_Comment, FS_GROUP, &idx);
- if (ac >= 0 && ac == group) {
- ok = 1;
- break;
- }
- }
- ac = ExtractFieldVal(fib->fib_Comment, FS_ACCESS, NULL);
- if (ac >= 0) { /* valid access field */
- if (ac <= access) { /* access ok */
- ok = 1;
- } else { /* access not ok */
- ok = 0;
- break;
- }
- }
- if (tmp = ParentDir(lock2)) { /* check the par.dir */
- UnLock(lock2);
- lock2 = tmp;
- fib->fib_Comment[0] = 0;
- Examine(lock2, fib);
- continue;
- }
- break;
- }
- UnLock(lock2);
- if (!ok) {
- error = WriteHeader('N', "Access Violation", 0);
- goto done;
- }
- }
- Examine(lock, fib);
- UnLock(lock);
- lock = NULL;
- if (fib->fib_DirEntryType > 0) {
- error = PutDir(str, access);
- } else {
- error = PutFile(str, access);
- }
- done:
- if (lock)
- UnLock(lock);
- free(fib);
- return((int)error);
- }
-
- int
- PutDir(name, access)
- char *name;
- int access;
- {
- long lock = Lock(name, SHARED_LOCK);
- FIB *fib = malloc(sizeof(FIB));
- static HDR Hdr;
- short error = 0;
- short ac;
-
- if (!lock || !Examine(lock, fib)) {
- WriteHeader('N', "Possible Disk Error", 0);
- error = 1;
- goto done;
- }
-
- ac = ExtractFieldVal(fib->fib_Comment, FS_ACCESS, NULL);
- if (ac >= 0 && ac > access) {
- error = WriteHeader('S', fib->fib_FileName, 0);
- goto done;
- }
-
- if (error = WriteHeader('D', fib->fib_FileName, 0))
- goto done;
- switch(ReadHeader(&Hdr)) {
- case 'Y':
- break;
- case 'S':
- goto done;
- case 'N':
- error = 1;
- break;
- default:
- error = 1;
- break;
- }
- if (error)
- goto done;
- while (ExNext(lock, fib)) { /* try to give him the files */
- if (fib->fib_DirEntryType > 0) {
- long oldlock = CurrentDir(lock);
- error = PutDir(fib->fib_FileName, access);
- CurrentDir(oldlock);
- if (error)
- break;
- } else {
- long oldlock = CurrentDir(lock);
- error = PutFile(fib->fib_FileName, access);
- CurrentDir(oldlock);
- if (error)
- break;
- }
- }
- if (!error)
- WriteHeader('E', "Possible Disk Error", 0);
- done:
- free(fib);
- if (lock)
- UnLock(lock);
- return((int)error);
- }
-
- int
- PutFile(name, access)
- char *name;
- int access;
- {
- long lock = Lock(name, SHARED_LOCK);
- long fh = NULL;
- FIB *fib = malloc(sizeof(FIB));
- static HDR Hdr;
- long len;
- short error = 0;
- short ac;
-
- if (!lock || !Examine(lock, fib)) {
- WriteHeader('N', "Possible Disk Error", 0);
- error = 1;
- goto done;
- }
-
- ac = ExtractFieldVal(fib->fib_Comment, FS_ACCESS, NULL);
- if (ac >= 0 && ac > access) {
- error = WriteHeader('S', fib->fib_FileName, 0);
- goto done;
- }
-
- fh = Open(name, 1005);
- if (fh == NULL) /* don't do anything if unable to open it */
- goto done;
- Seek(fh, 0L, 1);
- len = Seek(fh, 0L, 0);
- if (error = WriteHeader('F', fib->fib_FileName, len))
- goto done;
- switch(ReadHeader(&Hdr)) {
- case 'Y':
- Seek(fh, Hdr.Val, -1); /* start pos. */
- len -= Hdr.Val;
- if (len < 0)
- len = 0;
- break;
- case 'S':
- goto done;
- case 'N':
- error = 1;
- break;
- default:
- error = 1;
- break;
- }
- if (error)
- goto done;
- while (len) {
- long n = (len > sizeof(Buf)) ? sizeof(Buf) : len;
-
- if (Read(fh, Buf, n) != n) { /* read failed! */
- error = 10;
- goto done;
- }
- if (DWrite(Chan, Buf, n) != n) {
- error = 10;
- goto done;
- }
- len -= n;
- }
- done:
- free(fib);
- if (fh)
- Close(fh);
- if (lock)
- UnLock(lock);
- return((int)error);
- }
-
- int
- WriteHeader(c, str, len)
- char c;
- char *str;
- long len;
- {
- ubyte sl;
-
- if (str == NULL)
- str = "";
- sl = strlen(str);
-
- if (DWrite(Chan, &c, 1) < 0)
- return(1);
- if (DWrite(Chan, &sl,1) < 0)
- return(1);
- if (DWrite(Chan, str, sl) != sl)
- return(1);
- if (DWrite(Chan, &len, 4) != 4)
- return(1);
- return(0);
- }
-
- int
- ReadHeader(hdr)
- HDR *hdr;
- {
- ubyte sl;
- ubyte cmd;
-
- hdr->Cmd = -1;
- if (DRead(Chan, &cmd, 1) != 1)
- return(-1);
- if (DRead(Chan, &sl, 1) != 1)
- return(-1);
- if (sl >= sizeof(hdr->Str)) {
- return(-1);
- }
- if (DRead(Chan, hdr->Str, sl) != sl)
- return(-1);
- hdr->Str[sl] = 0;
- if (DRead(Chan, &hdr->Val, 4) != 4)
- return(-1);
- hdr->Cmd = cmd;
- return((int)hdr->Cmd);
- }
-
-
-